package com.site.service.impl.backend.system;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Component;

import com.site.dao.backend.system.MenuDao;
import com.site.dto.backend.system.ResourseBizBean;
import com.site.dto.backend.system.RoleBizBean;
import com.site.model.backend.system.ResourseInfo;
import com.site.service.backend.system.MenuService;
import com.site.service.backend.system.RoleService;
import com.site.util.MenuUtil;
import com.site.util.PropertyUtils;
import com.site.util.base.service.BaseServiceImpl;
import com.site.util.constant.Constants;
import com.site.util.exception.ApplicationException;
import com.site.util.exception.SystemException;
import com.site.util.extremetable.QueryPage;


/**
 * 菜单Service
 * @author Lee 2012-12-24 
 *
 */
@Component("menuService")
public class MenuServiceImpl extends BaseServiceImpl implements MenuService {

	private MenuDao menuDao;
	
	private RoleService roleService;
	
	@Override
	public Object doExecute(Object obj, String command) throws SystemException, ApplicationException {
		if(command.equals(COMMAND_UPDATE)){
			update((ResourseBizBean)obj);
		} else if(command.equals(COMMAND_DELETE)){
			delete((ResourseBizBean)obj);
		} else if(COMMAND_SAVE.equals(command)){
			save((ResourseBizBean)obj);
		}
		return null;
	}

	/**
	 * 增加菜单
	 * @param obj
	 * @return
	 */
	private void save(ResourseBizBean obj) {
		if(null != obj){
			obj.setName(getNewName());
			menuDao.save(obj);
		} else {
			log.info("菜单对象为空了,不能执行增加操作!");
		}
	}

	/**
	 * 逻辑删除菜单
	 * @param obj
	 */
	private void delete(ResourseBizBean obj) {
		if(null != obj){
			menuDao.delete(obj);
		} else {
			log.info("菜单对象为空了,不能执行删除操作!");
		}
	}

	/**
	 * 更新菜单
	 * @param obj
	 */
	private void update(ResourseBizBean obj) {
		if(null != obj){
			menuDao.update(obj);
		} else {
			log.info("菜单对象为空了,不能执行更新操作!");
		}
	}

	@Override
	public List<ResourseBizBean> getMenuList(QueryPage queryPage,ResourseBizBean resourseBizBean) {
		List<ResourseInfo> resourseInfoList =  menuDao.getMenuList(queryPage, resourseBizBean);
		if(null != resourseInfoList){
			return getResourseBizBeanList(resourseInfoList);
		} else {
			return null;
		}
	}
	/**
	 * 根据 po list 获得 vo list
	 * @param resourseInfoList
	 * @return
	 */
	private List<ResourseBizBean> getResourseBizBeanList(List<ResourseInfo> resourseInfoList) {
		List<ResourseBizBean> resourseBizBeanList = new ArrayList<ResourseBizBean>();
		
		if(null != resourseInfoList && resourseInfoList.size()> 0){
			for (ResourseInfo po : resourseInfoList) {
				if(po.getMarkDelete().equals("N")){
					ResourseBizBean vo = new ResourseBizBean();
					PropertyUtils.copyProperties(vo, po);
					if(null != po && po.getParentResourseInfo() == null){
						// 子节点
						if(null != po.getChildrenList() && po.getChildrenList().size() > 0 && po.getMarkDelete().equals("N")){
							ResourseBizBean vo1 = getVotoPo(po);
							if(null != vo1){
								vo = vo1;
							}
						}
					}
					resourseBizBeanList.add(vo);
				}
			}
		}
		return getShortMenu(resourseBizBeanList);
	}
	
	private ResourseBizBean getVotoPo(ResourseInfo po){
		ResourseBizBean tempVo = new ResourseBizBean();
		PropertyUtils.copyProperties(tempVo, po);
		if(po.getChildrenList().size() > 0 && po.getChildrenList() !=null){
			List<ResourseBizBean> temp = new ArrayList<ResourseBizBean>();
			for (ResourseInfo po1 : po.getChildrenList()) {
				if(null != po1 && po1.getMarkDelete() != null && po1.getMarkDelete().equals("N")){
					ResourseBizBean vo = new ResourseBizBean();
					PropertyUtils.copyProperties(vo, po1);
					
					if(null != po1 && null != po1.getChildrenList() && po1.getChildrenList().size() > 0){
						vo = getVotoPo(po1);
					}
					vo.setParentResourseBizBean(tempVo);
					temp.add(vo);
				}
			}
			tempVo.setChildrenList(temp);
		}
		return tempVo;
	}

	public MenuDao getMenuDao() {
		return menuDao;
	}

	@Resource
	public void setMenuDao(MenuDao menuDao) {
		this.menuDao = menuDao;
	}

	@Override
	public Integer getIdByTitle(String title) {
		return menuDao.getIdByTitle(title);
	}

	@Override
	public List<ResourseBizBean> getUserMenu(Integer id) {
		
		List<ResourseBizBean> resourseBizBeanList = new ArrayList<ResourseBizBean>();
		// 获取该用户所属所有角色
		List<RoleBizBean> roleBizBeanList = roleService.getUserRoles(id, null);
		if(null != roleBizBeanList && roleBizBeanList.size() > 0){
			// 角色下的菜单
			//
			List<Long> roleIds = new ArrayList<Long>();
			for (Iterator<RoleBizBean> iterator = roleBizBeanList.iterator(); iterator.hasNext();) {
				RoleBizBean role = iterator.next();
				if(null != role && null != role.getId()){
					roleIds.add(role.getId());
					// 通过角色找菜单
					// List<ResourseBizBean> resourseBizBeans = roleService.getRoleResourse(role.getId());
					// if(null != resourseBizBeans && resourseBizBeans.size() > 0){
						//resourseBizBeanList.addAll(resourseBizBeans);
					// }
					
				}
			}
			List<ResourseBizBean> resourseBizBeans = roleService.getRoleResourse(roleIds);
			if(null != resourseBizBeans && resourseBizBeans.size() > 0){
				resourseBizBeanList.addAll(resourseBizBeans);
			}
		}
		
		return getShortMenu(resourseBizBeanList);
	}
	
	/**
	 * 菜单排序比较器
	 * @author Lee
	 *
	 */
	@SuppressWarnings("rawtypes")
	private class Mycomparator implements Comparator{

		public int compare(Object o1,Object o2) {
			if (o1 instanceof ResourseBizBean) {
				ResourseBizBean p1=(ResourseBizBean)o1;
				ResourseBizBean p2=(ResourseBizBean)o2; 
				if(null != p1 && null != p1.getOrderBy() && null != p2 && null != p2.getOrderBy() && p1.getOrderBy().intValue() > p2.getOrderBy().intValue())
				  return 1;
				else
				  return 0;
			} else if (o1 instanceof ResourseInfo) {
				ResourseInfo p1=(ResourseInfo)o1;
				ResourseInfo p2=(ResourseInfo)o2; 
				if(null != p1 && null != p1.getOrderBy() && null != p2 && null != p2.getOrderBy() && p1.getOrderBy().intValue() > p2.getOrderBy().intValue())
				  return 1;
				else
				  return 0;
			}
			return 0;
		}

	}
	@Override
	public List<ResourseBizBean> getMenu(QueryPage queryPage) {
		List<ResourseInfo> resourseInfoList =  menuDao.getMenu(queryPage);
		if(null != resourseInfoList){
			return getResourseBizBeanList(resourseInfoList);
		} else {
			return null;
		}
	}
	
	@Resource
	public void setRoleService(RoleService roleService) {
		this.roleService = roleService;
	}
	public RoleService getRoleService() {
		return roleService;
	}

	@Override
	public List<ResourseBizBean> getUserMenu(Integer id,HttpServletRequest request) {
		// 获取该用户所属所有角色
		List<RoleBizBean> roleBizBeanList = roleService.getUserRoles(id, null);
		// 所有大角色菜单
		Set<ResourseBizBean> menuRole = new HashSet<ResourseBizBean>();
		// 判断用户的角色是否有菜单
		if(null != roleBizBeanList){
			// 保存不同角色的菜单。有重复数据
			for (RoleBizBean roleBizBean : roleBizBeanList) {
				Set<ResourseBizBean> resSet= MenuUtil.getInstance().getRoleMenu(roleBizBean.getId(), request);
				if(null != resSet && resSet.size() > 0){
					menuRole.addAll(resSet);
				}
			}
			// 去掉禁用的菜单
			List<ResourseBizBean> user_Menu = new ArrayList<ResourseBizBean>();
			for (Iterator<ResourseBizBean> it = menuRole.iterator(); it.hasNext();) {
				ResourseBizBean mVo = it.next();
				if ("N".equals(mVo.getMarkDelete()) && mVo.getParentResourseBizBean() == null) {
					user_Menu.add(mVo);
				}
			}
			
			// 去掉重复菜单 start
			// 没有去掉重复的数据
		    List<ResourseBizBean> oldMenu = getShortMenu(user_Menu);
		    List<ResourseBizBean> newMenu = null;
		    if(oldMenu != null && oldMenu.size() > 0){
			    // 去掉重复后的数据
		    	newMenu = new ArrayList<ResourseBizBean>();
			    // 循环就菜单
			    for (Iterator<ResourseBizBean> iterator = oldMenu.iterator(); iterator.hasNext();) {
					ResourseBizBean resourseBizBean = iterator.next();
					// 判断第一级菜单是否已经存在
					if(newMenu.contains(resourseBizBean)){
						// 保存所有新子菜单
						List<ResourseBizBean> newChildrens = newMenu.get(newMenu.indexOf(resourseBizBean)).getChildrenList();
						// 循环旧菜单的子菜单，判断新菜单里面是否已经存在旧菜单的菜单，如果存在就不添加，反之增加
						for (ResourseBizBean oldChildren : resourseBizBean.getChildrenList()) {
							if(!newChildrens.contains(oldChildren)){
								newChildrens.add(oldChildren);
							}
						}
					} else {
						newMenu.add(resourseBizBean);
					}
				}
			    // 去掉重复菜单 end
		    }
		    
			return newMenu;
		}
		return null;
	}
	/**
	 * 排序
	 * @param user_Menu
	 * @return
	 */
	@SuppressWarnings("all")
	private List<ResourseBizBean> getShortMenu(List<ResourseBizBean> user_Menu){
		if(null != user_Menu && user_Menu.size() > 0){
			ResourseBizBean[] menus = new ResourseBizBean[] {};
			if (user_Menu.size() > 0) {
				menus = (ResourseBizBean[]) (user_Menu.toArray(new ResourseBizBean[0]));
			}
			
			List<ResourseBizBean> menuBizBeanList = new ArrayList<ResourseBizBean>();
			if ( menus.length > 0) {
				menuBizBeanList = Arrays.asList(menus);
				//按OrderBy排序
				Comparator comp = new Mycomparator();
				Collections.sort(menuBizBeanList,comp);
			}
			if(null != menuBizBeanList && menuBizBeanList.size() > 0){
				for (ResourseBizBean resourseBizBean : menuBizBeanList) {
					if(null != resourseBizBean && resourseBizBean.getChildrenList() != null && resourseBizBean.getChildrenList().size() >0){
						resourseBizBean.setChildrenList(getShortMenu(resourseBizBean.getChildrenList()));
					}
				}
			}
			return menuBizBeanList;
		}
		return null;
	}
	/**
	 * 获得name值
	 * @return
	 */
	private String getNewName() {
		Integer maxId = null;
		maxId = menuDao.getMaxId();
		if (maxId == null) {
			maxId = 1;
		}
		String name = Constants.MENU_PREFIX + String.format("%03d", maxId + 1);
		return name;
	}
}
